package com.dic.mall.product.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.dic.mall.product.entity.CategoryEntity;
import com.dic.mall.product.service.CategoryService;
import com.dic.mall.product.vo.Catelog2Vo;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author ：leeliang
 * @date ：Created in 2021/3/13 20:32
 * @description：
 * @modified By：
 * @version: $
 */
@Controller
public class IndexController {
    @Autowired
    private CategoryService categoryService;

    @GetMapping({"/","/index"})
    public String index(Model model){
        List<CategoryEntity> categorys = categoryService.getLevel1Categorys();
        model.addAttribute("categorys",categorys);
        return "index";
    }

    @Autowired
    private StringRedisTemplate stringRedisTemplate;



    @GetMapping({"/index/catalog.json"})
    @ResponseBody
    public Map<String, List<Catelog2Vo>> getCatalogJson(){
        Map<String, List<Catelog2Vo>> catalogJson = categoryService.getCatalogJson();
        return catalogJson;
    }

    @Autowired
    RedissonClient redissonClient;

    @GetMapping({"/hello"})
    @ResponseBody
    public String hello(){
        //可重入锁
        RLock lock = redissonClient.getLock("my-lock");
//        lock.lock(); //阻塞式等待，默认时间30s,
        //1.锁的自动续期
        lock.lock(10, TimeUnit.SECONDS);
        System.out.println("加锁成功"+Thread.currentThread().getName());
        try{
            Thread.sleep(30000);
            System.out.println("业务执行成功");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
            System.out.println("解成功"+Thread.currentThread().getName());

        }
        return "hello";
    }



    @RequestMapping("/write")
    @ResponseBody
    public  String writeValue(){
        RReadWriteLock lock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = null;
        String s = null;
        try{
            rLock = lock.writeLock();
            rLock.lock();
            System.out.println("写加锁");
            s = UUID.randomUUID().toString();
            stringRedisTemplate.opsForValue().set("writeValue",s);
            Thread.sleep(30*1000);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            rLock.unlock();
            System.out.println("写解锁");
        }
        return s;
    }


    @RequestMapping("/read")
    @ResponseBody
    public  String readValue(){
        RReadWriteLock rwLock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = rwLock.readLock();
        rLock.lock();
        String writeValue = null;
        System.out.println("读加锁");
        try{
            writeValue = stringRedisTemplate.opsForValue().get("writeValue");
            Thread.sleep(10*1000);
        }catch (Exception e){
        }finally {
            rLock.unlock();
            System.out.println("读解锁");
        }
        return writeValue;
    }

    @RequestMapping("/park")
    @ResponseBody
    public String park() throws InterruptedException {
        RSemaphore park = redissonClient.getSemaphore("park");
//        park.acquire();//获取一个值，占一个停车位（阻塞方法）
        boolean b = park.tryAcquire();//非阻塞式
        if(b){
            //业务代码
        }else{

        }
        return "ok";
    }

    @RequestMapping("/go")
    @ResponseBody
    public String go(){
        RSemaphore park = redissonClient.getSemaphore("park");
        park.release();//释放一个停车位
        return "ok";
    }

    @RequestMapping("/door")
    @ResponseBody
    public String door() throws InterruptedException {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.trySetCount(3);
        door.await();
        return "学校放假了";
    }

    @RequestMapping("/gogo/{id}")
    @ResponseBody
    public String gogo(@PathVariable("id")Long id){
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();
        return id+"班级学生走完了";
    }

}
